/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.views.impl;

import cn.easyplatform.entities.BaseEntity;
import cn.easyplatform.entities.beans.api.ApiBean;
import cn.easyplatform.entities.beans.page.BindVariable;
import cn.easyplatform.entities.beans.page.PageBean;
import cn.easyplatform.entities.beans.project.ProjectBean;
import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.studio.utils.TemplateUtil;
import cn.easyplatform.studio.vos.*;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.studio.web.editors.TableInfo;
import cn.easyplatform.studio.web.editors.help.GuideConfigEditor;
import cn.easyplatform.studio.web.views.View;
import cn.easyplatform.web.ext.introJs.Action;
import cn.easyplatform.web.ext.zul.BandboxExt;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.ext.Disable;
import org.zkoss.zul.*;

import java.util.List;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public abstract class AbstractView<T> implements View, EventListener<Event> {

    protected EditorCallback<T> cb;

    protected Window win;

    private Component component;
    /**
     * @param cb
     */
    protected AbstractView(Component component, EditorCallback<T> cb) {
        this.component = component;
        this.cb = cb;
    }

    protected AbstractView(EditorCallback<T> cb) {
        this.cb = cb;
    }
    @Override
    public void doOverlapped() {
        win = createWindow();
        win.setPosition("center");
        win.doOverlapped();
        setWindow(win);
    }

    @Override
    public void doOverlapped(String position) {
        win = createWindow();
        win.setPosition(position);
        win.doOverlapped();
        setWindow(win);
    }

    @Override
    public void doHighlighted() {
        win = createWindow();
        win.setPosition("center");
        win.doHighlighted();
        setWindow(win);
    }

    private Window createWindow() {
        Window win = new Window();
        win.setTitle(cb.getTitle());
        win.setClosable(true);
        win.setPage(cb.getPage());
        win.setMaximizable(true);
        win.setHeight("500px");
        win.setWidth("850px");
        win.setSizable(true);
        win.setFocus(true);
        Borderlayout layout = new Borderlayout();
        Center body = new Center();
        body.setHflex("1");
        body.setVflex("1");
        body.setBorder("none");
        body.setParent(layout);
        win.appendChild(layout);
        createHeader(layout);
        createContent(body);
        createFooter(layout);
        return win;
    }

    protected void createFooter(Component parent) {
    }

    protected void createHeader(Component parent) {
    }

    protected abstract void createContent(Component parent);

    private void setWindow(final Window win) {
        win.addEventListener(Events.ON_CLOSE, new EventListener<Event>() {
            @Override
            public void onEvent(Event event) throws Exception {
                onCloseClick(win);
            }
        });
        if (component != null && (component instanceof Button ||
                component instanceof BandboxExt || component instanceof Bandbox || component instanceof Toolbarbutton
                || component instanceof A)) {
            ((Disable) component).setDisabled(true);
        }
    }

    protected void onCloseClick(Window win) {
        if (component != null && (component instanceof Button ||
                component instanceof BandboxExt || component instanceof Bandbox || component instanceof Toolbarbutton
                || component instanceof A)) {
            ((Disable) component).setDisabled(false);
        }
    }
    /*
     * 以下是工厂方法
     */
    public final static View createLogicView(EditorCallback<String> cb, Component component) {
        return new LogicView(cb, component);
    }

    public final static View createEntityView(EditorCallback<String> cb,
                                              String selector, Component component) {
        return new EntityView(cb, selector, component);
    }

    public final static View createEntityView(EditorCallback<String> cb,
                                              String selector, EntityView.OnMsgListener msgListener, Component component) {
        return new EntityView(cb, selector, msgListener, component);
    }

    public final static View createQueryView(EditorCallback<String> cb,
                                             BizQueryVo vo, boolean isMultiple, Component component, String... labels) {
        return new QueryView(cb, vo, isMultiple, component, labels);
    }

    public final static View createIconView(EditorCallback<String> cb,
                                            String scope, Component component) {
        return new IconView(cb, scope, component);
    }

    public final static View createEchartView(EditorCallback<String> cb,
                                              String scope) {
        return new EchartView(cb, scope);
    }

    public final static View createSelectEchartView(EditorCallback<String> cb,String scope) {
        return new SelectEchartView(cb,scope);
    }

    public final static View createCodeView(EditorCallback<String> cb,
                                            String mode, Component component) {
        return new CodeView(cb, mode, component);
    }

    public final static View createFileListView(EditorCallback<String> cb,
                                                String scope, Component component) {
        return new FileListView(cb, scope, component);
    }

    public final static View createDatasourceView(EditorCallback<String> cb, Component component) {
        return new DatasourceView(cb, component);
    }

    public final static View createApiRefIdView(EditorCallback<String> cb, Component component){
        return new ApiRefidView(cb, component);
    }

    public final static View createCronView(EditorCallback<String> cb) {
        return new CronView(cb);
    }

    public final static View createTableView(EditorCallback<TableInfo> cb,
                                             boolean closable, Component component) {
        return new TableView(cb, closable, component);
    }

    public final static View createComponentView(EditorCallback<String> cb,
                                                 String selector, Component component) {
        return new EntityView(cb, selector, component);
    }

    public final static View createVersionView(EditorCallback<String> cb,
                                               String orig) {
        return new VersionView(cb, orig);
    }

    public final static View createDicDetailView(EditorCallback<String> cb, List<DicDetailVo> dicDetailVoList) {
        return new DicContentView(cb, dicDetailVoList);
    }

    public final static View createRootTaskView(EditorCallback<String> cb, String entityId) {
        return new RootTaskContentView(cb, entityId);
    }

    public final static View createFileView(EditorCallback<String> cb, MediaFileVo fileVo) {
        return new FileContentView(cb, fileVo);
    }

    public final static View createThemeView(EditorCallback<String> cb) {
        return new ThemeContentView(cb);
    }

    public final static View createTableMultipleView(EditorCallback<List<TableBean>> cb, Component component) {
        return new TableExportView(cb, component);
    }

    public final static View createDbMultipleView(EditorCallback<List<EntityVo>> cb, Component component) {
        return new DbExportView(cb, component);
    }

    public final static View createExcelImportView(EditorCallback<List<Object>> cb, Object data,
                                                   String type, Component component) {
        return new ExcelImportView(cb, data, type, component);
    }

    public final static View createActionView(EditorCallback<List<Action>> cb, List<Action> actionList,
                                              GuideConfigEditor.GuideConfigType type, Component component) {
        return new ActionView(cb, actionList, type, component);
    }

    public final static View createGuideView(EditorCallback<GuideConfigVo> cb,
                                             List<GuideConfigVo> guideConfigVos, Component component) {
        return new GuideView(cb, guideConfigVos, component);
    }

    public final static View createElementView(EditorCallback<ElementVo> cb,
                                               GuideConfigEditor.GuideConfigType type, Component component) {
        if (type == GuideConfigEditor.GuideConfigType.GuideConfigStudio)
            return new ElementView(cb, component);
        else
            return new AppElementView(cb, component);
    }

    public final static View createPropertiesView(EditorCallback<String> cb) {
        return new PropertiesView(cb);
    }

    public final static View createApiTestView(EditorCallback<ApiBean> cb,String scope) {
        return new ApiTestView(cb,scope);
    }

    public final static View createAppPageImageView(EditorCallback<String> cb,String pathName,TemplateUtil.TemplateType template, Component component) {
        return new AppPageImageView(cb,pathName, template, component);
    }

    public final static View createAppPageEditorView(EditorCallback<String> cb, String xml, Component component) {
        return new AppPageEditorView(cb, xml, component);
    }

    public final static View createAppPageTemplateView(EditorCallback<String> cb,String pathName,TemplateUtil.TemplateType template, Component component) {
        return new AppPageTemplateView(cb,pathName,template, component);
    }

    public final static View createAppPageProductView(EditorCallback<String> cb,List<EntityVo> entityVos, Component component) {
        return new AppPageProductView(cb,entityVos,component);
    }

    public final static View createModuleImageView(EditorCallback<List<String>> cb, List<String> pathList, Component component) {
        return new ModuleImageView(cb, pathList, component);
    }

    public final static View createToolProperties(EditorCallback<String> cb) {
        return new ToolPropertiesView(cb);
    }

    public final static View createSqlFieldView(EditorCallback<String> cb, List<TableBean> tableBeanList) {
        return new SqlFieldView(cb, tableBeanList);
    }

    public final static View createCodeThemeContentView(EditorCallback<String> cb) {
        return new CodeThemeContentView(cb);
    }

    public final static View createTemplate(EditorCallback<PageBean> cb, PageTemplateView.PageTemplateType templateType,
                                            Component component, PageBean pageBean) {
        return new PageTemplateView(component, cb, templateType, pageBean);
    }

    public final static View createRule(EditorCallback<String> cb, Component component) {
        return new RuleView(component, cb);
    }

    public final static View createBindVariable(EditorCallback<List<BindVariable>> cb, Component component) {
        return new BindVariableView(component, cb);
    }

    public final static View createRoleAccessView(Component component, List<BaseEntity> baseEntities, List<AccessVo> access,
                                                  EditorCallback<List<RoleAccessVo>> cb) {
        return new SelectedMenuAccessView(component, cb, baseEntities, access);
    }

    public final static View createMenuAccessView(Component component, List<AccessVo> accessVos, EditorCallback<List<BaseEntity>> cb) {
        return new MenuAccessView(component, cb, accessVos);
    }

    public final static View createDicCodeView(Component component, EditorCallback<String> cb) {
        return new DicDetailView(component, cb);
    }

    public final static View createTableCodeLabelView(Component component, EditorCallback<TableCodeLabelVo> cb) {
        return new TableCodeLabelView(component, cb);
    }

    public final static View createLinkView(Component component, EditorCallback<List<RoleVo>> cb, String projectID, String userID) {
        return new LinkView(component, cb, projectID, userID);
    }

    public final static View createProject(Component component, EditorCallback<List<ProjectBean>> cb, String userId) {
        return new CreateProjectView(component, cb, userId);
    }

    public final static View createCustomWidget(EditorCallback<List<CustomWidgetGroupVo>> cb) {
        return new CustomWidgetView(cb);
    }

    public final static View createCustomWidgetSet(EditorCallback<CustomWidgetVo> cb) {
        return new CustomWidgetSetView(cb);
    }

}
